home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Resources / Chat & Communication / Digsby build 37 / digsby_setup.exe / lib / M2Crypto / SSL / Checker.pyo (.txt) < prev    next >
Python Compiled Bytecode  |  2008-10-13  |  5KB  |  151 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.5)
  3.  
  4. from M2Crypto import util, EVP, m2
  5. import re
  6.  
  7. class SSLVerificationError(Exception):
  8.     pass
  9.  
  10.  
  11. class NoCertificate(SSLVerificationError):
  12.     pass
  13.  
  14.  
  15. class WrongCertificate(SSLVerificationError):
  16.     pass
  17.  
  18.  
  19. class WrongHost(SSLVerificationError):
  20.     
  21.     def __init__(self, expectedHost, actualHost, fieldName = 'commonName'):
  22.         if fieldName not in ('commonName', 'subjectAltName'):
  23.             raise ValueError('Unknown fieldName, should be either commonName or subjectAltName')
  24.         
  25.         SSLVerificationError.__init__(self)
  26.         self.expectedHost = expectedHost
  27.         self.actualHost = actualHost
  28.         self.fieldName = fieldName
  29.  
  30.     
  31.     def __str__(self):
  32.         s = 'Peer certificate %s does not match host, expected %s, got %s' % (self.fieldName, self.expectedHost, self.actualHost)
  33.         if isinstance(s, unicode):
  34.             s = s.encode('utf8')
  35.         
  36.         return s
  37.  
  38.  
  39.  
  40. class Checker:
  41.     numericIpMatch = re.compile('^[0-9]+(\\.[0-9]+)*$')
  42.     
  43.     def __init__(self, host = None, peerCertHash = None, peerCertDigest = 'sha1'):
  44.         self.host = host
  45.         self.fingerprint = peerCertHash
  46.         self.digest = peerCertDigest
  47.  
  48.     
  49.     def __call__(self, peerCert, host = None):
  50.         if peerCert is None:
  51.             raise NoCertificate('peer did not return certificate')
  52.         
  53.         if host is not None:
  54.             self.host = host
  55.         
  56.         if self.fingerprint:
  57.             if self.digest not in ('sha1', 'md5'):
  58.                 raise ValueError('unsupported digest "%s"' % self.digest)
  59.             
  60.             if (self.digest == 'sha1' or len(self.fingerprint) != 40 or self.digest == 'md5') and len(self.fingerprint) != 32:
  61.                 raise WrongCertificate('peer certificate fingerprint length does not match')
  62.             
  63.             der = peerCert.as_der()
  64.             md = EVP.MessageDigest(self.digest)
  65.             md.update(der)
  66.             digest = md.final()
  67.             if util.octx_to_num(digest) != int(self.fingerprint, 16):
  68.                 raise WrongCertificate('peer certificate fingerprint does not match')
  69.             
  70.         
  71.         if self.host:
  72.             hostValidationPassed = False
  73.             self.useSubjectAltNameOnly = False
  74.             
  75.             try:
  76.                 subjectAltName = peerCert.get_ext('subjectAltName').get_value()
  77.                 if not self._splitSubjectAltName(self.host, subjectAltName):
  78.                     raise WrongHost(expectedHost = self.host, actualHost = subjectAltName, fieldName = 'subjectAltName')
  79.                 
  80.                 hostValidationPassed = True
  81.             except LookupError:
  82.                 pass
  83.  
  84.             if not (self.useSubjectAltNameOnly) and not hostValidationPassed:
  85.                 hasCommonName = False
  86.                 commonNames = ''
  87.                 for entry in peerCert.get_subject().get_entries_by_nid(m2.NID_commonName):
  88.                     hasCommonName = True
  89.                     commonName = entry.get_data().as_text()
  90.                     if not commonNames:
  91.                         commonNames = commonName
  92.                     else:
  93.                         commonNames += ',' + commonName
  94.                     if self._match(self.host, commonName):
  95.                         hostValidationPassed = True
  96.                         break
  97.                         continue
  98.                 
  99.                 if not hasCommonName:
  100.                     raise WrongCertificate('no commonName in peer certificate')
  101.                 
  102.                 if not hostValidationPassed:
  103.                     raise WrongHost(expectedHost = self.host, actualHost = commonNames, fieldName = 'commonName')
  104.                 
  105.             
  106.         
  107.         return True
  108.  
  109.     
  110.     def _splitSubjectAltName(self, host, subjectAltName):
  111.         self.useSubjectAltNameOnly = False
  112.         for certHost in subjectAltName.split(','):
  113.             certHost = certHost.lower().strip()
  114.             if certHost[:4] == 'dns:':
  115.                 self.useSubjectAltNameOnly = True
  116.                 if self._match(host, certHost[4:]):
  117.                     return True
  118.                 
  119.             self._match(host, certHost[4:])
  120.         
  121.         return False
  122.  
  123.     
  124.     def _match(self, host, certHost):
  125.         host = host.lower()
  126.         certHost = certHost.lower()
  127.         if host == certHost:
  128.             return True
  129.         
  130.         if certHost.count('*') > 1:
  131.             return False
  132.         
  133.         if self.numericIpMatch.match(host) or self.numericIpMatch.match(certHost.replace('*', '')):
  134.             return False
  135.         
  136.         if certHost.find('\\') > -1:
  137.             return False
  138.         
  139.         certHost = certHost.replace('.', '\\.')
  140.         certHost = certHost.replace('*', '[^\\.]*')
  141.         if re.compile('^%s$' % certHost).match(host):
  142.             return True
  143.         
  144.         return False
  145.  
  146.  
  147. if __name__ == '__main__':
  148.     import doctest
  149.     doctest.testmod()
  150.  
  151.